#vars

################################################################
#TODO change project name here, and run "make init" to init this uva project.
projectname = Primes
################################################################

.PHONY: default memcheck memcheck-full docs uva output prof runmainprof 

#build options for uva online judge
UVAFLAGS = -lm -lcrypt -O2 -pipe -DONLINE_JUDGE

#general g++ options
CXXFLAGS = -ansi -pedantic -Wall -DONLINE_JUDGE

#build options for CppUnit
CPPUNITFLAGS = $(CXXFLAGS) -lcppunit -ldl -DTEST

#profiling option
#for gprof and gcov
PROFFLAGS = -pg -fprofile-arcs -ftest-coverage

memcheck = valgrind
memcheckfull = valgrind --leak-check=full --show-reachable=yes

builddir = ./build
utilsdir = ./utils

testapp = $(builddir)/test
mainapp = $(builddir)/main
uvaapp = $(builddir)/uva

mainprofapp = $(builddir)/main.prof

testfile = Test$(projectname).h
samplein = sample.in
sampleout = sample.out
uvasrcfile = uva.c++

samplerun = $(mainapp) < $(samplein) |diff - $(sampleout)
sampleprofrun = $(mainprofapp) < $(samplein) >/dev/null 2>&1

default: check
all : $(mainapp) $(testapp) docs TAGS uva output

#run tests
check: runtests runsamplerun
runtests: $(testapp)
	$<
runsamplerun: $(mainapp) $(samplein) $(sampleout)
	$(samplerun)

#show performance
perf: $(testapp) $(mainapp)
	$(utilsdir)/timeit

prof: runmainprof

#main.gcno is made when compiling
#main.gcda is made when running
runmainprof: main.c++
	$(CXX) $(CXXFLAGS) $(PROFFLAGS) $< -o $(mainprofapp)
	$(sampleprofrun)
	gprof -b $(mainprofapp) >gprof.out
	@rm gmon.out
	@echo "gprof flat profile generated. see gprof.out."
	gcov main.c++ >/dev/null
	@mv main.c++.gcov gcov.out
	@rm *.gcov main.gcno main.gcda
	@mv gcov.out main.c++.gcov
	@echo "gcov output generated. see main.c++.gcov."

#quick prof, run 100 times then sum.
qprof: runmainqprof
runmainqprof: $(utilsdir)/quickgprof $(mainprofapp)
	$<

#run tests with memcheck
memcheck: $(testapp)
	$(memcheck) $<

memcheck-full: $(testapp)
	$(memcheckfull) $<

docs: Doxyfile main.c++ $(testfile)
	doxygen Doxyfile

output: $(projectname).out Test$(projectname).out

$(projectname).out: $(projectname).in $(mainapp)
	$(memcheck) $(mainapp) < $(projectname).in > $(projectname).out 2>&1
Test$(projectname).out: $(testapp)
	$(memcheck) $(testapp) > Test$(projectname).out 2>&1
TAGS: main.c++ Test$(projectname).h
	etags $^
tags: TAGS

clean: clean-docs 
	rm -rf $(builddir)/*
	rm -rf $(uvasrcfile) $(projectname).out Test$(projectname).out
clean-docs:
	rm -rf html/*
clean-TAGS:
	rm -rf TAGS

#real build commands
$(mainapp): main.c++
	$(CXX) $(CXXFLAGS) $< -o $@

$(testapp): main.c++ Test$(projectname).h
	$(CXX) $(CPPUNITFLAGS) $< -o $@

uva: $(uvaapp)

$(uvaapp): $(uvasrcfile)
	$(CXX) $(UVAFLAGS) $^ -o $@

#generate a file for uva, by removing all comments in main.c++
$(uvasrcfile): main.c++
	$(utilsdir)/generate_uva.c++

#init a UVa CS371p project
init: $(utilsdir)/initproject
	$< $(projectname)
